package com.vay.de.dang.online.util;

import android.annotation.SuppressLint;
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.HandlerThread;

import androidx.annotation.NonNull;

import com.vay.de.dang.online.web.BaseApi;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationAvailability;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;

import java.util.List;
import java.util.Locale;

public class LocationHelper {

    private static LocationHelper _instance;
    private Context mContext;
    private FusedLocationProviderClient fusedLocationClient;
    private LocationManager locationManager;
    private LocationRequest locationRequest;
    private LocationCallback locationCallback;
    private Location mLocation;
    private String mAddress;
    private String mLocationAddress;
    private String mCity;
    private HandlerThread handlerThread;

    private LocationHelper(Context context) {
        mContext = context;
        init();
    }

    public static LocationHelper create(Context context) {
        if (_instance == null) _instance = new LocationHelper(context);
        return _instance;
    }

    public static LocationHelper getInstance() {
        return _instance;
    }

    private void init() {
        handlerThread = new HandlerThread("#Location");
        handlerThread.start();
    }

    private void handleLocation(Location location) {
        if (location != null) {
            BaseApi.log("Location Ok, lat=" + location.getLatitude() + ",lng=" + location.getLongitude());
            this.mLocation = location;
            //double lat = location.getLatitude();
            //double lng = location.getLongitude();
            //String url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=" + lat + "," + lng
            //        + "&language=" + Locale.getDefault().getLanguage() + "&sensor=false";

            try {
                Geocoder gc = new Geocoder(mContext, Locale.getDefault());
                List<Address> result = gc.getFromLocation(location.getLatitude(),
                        location.getLongitude(), 1);
                if (result != null && result.size() > 0) {
                    Address address = result.get(0);
                    mCity = address.getLocality();
                    mAddress = address.getAddressLine(0);
                    mLocationAddress = address.getAdminArea() + "-" + address.getSubAdminArea();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            BaseApi.log("警告： 定位失败!!!");
        }
    }

    @SuppressLint("MissingPermission")
    public void requestLocation() {

        BaseApi.log("请求定位");

        /////////////////// google sdk ////////////////
        googleSdkLocation();

        ////////////////// GPS ////////////////
        try {
            LocationListener gpsListener = new LocationListener() {

                @Override
                public void onLocationChanged(@NonNull Location location) {
                    handleLocation(location);
                    locationManager.removeUpdates(this);
                }

                @Override
                public void onLocationChanged(@NonNull List<Location> locations) {
                    if (locations.size() > 0) {
                        handleLocation(locations.get(0));
                        locationManager.removeUpdates(this);
                    }
                }

                @Override
                public void onFlushComplete(int requestCode) {

                }

                @Override
                public void onProviderDisabled(@NonNull String provider) {
                    BaseApi.log("GPS 无效");
                }
            };
            locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
            locationManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, gpsListener, handlerThread.getLooper());
        } catch (Exception e) {
            e.printStackTrace();
        }

        ////////////////// 网络定位 ////////////////
        try {
            LocationListener networkListener = new LocationListener() {

                @Override
                public void onLocationChanged(@NonNull Location location) {
                    handleLocation(location);
                    locationManager.removeUpdates(this);
                }

                @Override
                public void onLocationChanged(@NonNull List<Location> locations) {
                    if (locations.size() > 0) {
                        handleLocation(locations.get(0));
                        locationManager.removeUpdates(this);
                    }
                }

                @Override
                public void onFlushComplete(int requestCode) {

                }

                @Override
                public void onProviderDisabled(@NonNull String provider) {
                    BaseApi.log("网络定位 无效");
                }
            };

            locationManager.requestSingleUpdate(LocationManager.NETWORK_PROVIDER, networkListener, handlerThread.getLooper());
        } catch (Exception e) {
            e.printStackTrace();
            BaseApi.log("网络定位异常: " + e.getMessage());
        }
    }

    public void stopLocation() {
        if (fusedLocationClient != null && locationCallback != null) {
            fusedLocationClient.removeLocationUpdates(locationCallback);
        }
    }

    public Location getLocation() {
        return mLocation;
    }

    public String getAddress() {
        return mAddress;
    }

    public String getCity() {
        return mCity;
    }

    public String getLocationAddress() {
        return mLocationAddress;
    }

    private void googleSdkLocation() {
        BaseApi.log("Google Request Location");
        try {
            fusedLocationClient = LocationServices.getFusedLocationProviderClient(mContext);
            locationRequest = new LocationRequest();
            locationRequest.setInterval(1000);
            locationRequest.setFastestInterval(5000);
            locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            locationCallback = new LocationCallback() {
                @Override
                public void onLocationResult(LocationResult locationResult) {
                    if (locationResult != null && locationResult.getLastLocation() != null) {
                        handleLocation(locationResult.getLastLocation());
                    }
                }

                @Override
                public void onLocationAvailability(LocationAvailability locationAvailability) {
                    //super.onLocationAvailability(locationAvailability);
                }
            };

            // google Location
            fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, handlerThread.getLooper());
        } catch (Exception e) {
            e.printStackTrace();
            BaseApi.log("定位异常: " + e.getMessage());
        }
    }
}
